package edu.caltech.android;

import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import android.content.Context;
import android.database.Cursor;
import android.database.DataSetObserver;
import android.graphics.drawable.Drawable;
import android.widget.Toast;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.OverlayItem;

/**
 * This class extends the EarthquakeOverlay from PA2AD to be an ItemizedOverlay,
 * with informative displays when an overlay item is tapped.
 * 
 * Portions of this code from Professional Android 2 Application Development,
 * ISBN: 978-0-470-56552-0, copyright Wiley Publishing Inc: 2010, by Reto Meier,
 * published under the Wrox imprint are used by permission of Wiley Publishing,
 * Inc. All rights reserved. This book and the Wrox code are available for
 * purchase or download at www.wrox.com
 * 
 * @author mfaulk
 * 
 */
public class EarthquakeItemizedOverlay extends ItemizedOverlay<OverlayItem> {
	@SuppressWarnings("unused")
	private static final String TAG = "EarthquakeItemizedOverlay";
	private Cursor quakeCursor;
	private List<QuakeOverlayItem> myOverlays;

	private final Context context;

	public EarthquakeItemizedOverlay(Drawable defaultMarker,
			Cursor quakeCursor, Context context) {
		super(boundCenterBottom(defaultMarker));
		this.context = context;
		myOverlays = new ArrayList<QuakeOverlayItem>();
		populate();

		this.quakeCursor = quakeCursor;
		this.quakeCursor.registerDataSetObserver(new DataSetObserver() {
			@Override
			public void onChanged() {
				refreshQuakeLocations();
			}
		});

		refreshQuakeLocations();
	}

	@Override
	protected OverlayItem createItem(int i) {
		return myOverlays.get(i);
	}

	@Override
	public int size() {
		return myOverlays.size();
	}

	private void refreshQuakeLocations() {
		//Log.v(TAG, "refreshQuakeLocations");
		myOverlays.clear();
		if (quakeCursor.moveToFirst()) {
			do {
				// convert to microdegrees for use with GeoPoint
				Double latE6 = quakeCursor
						.getFloat(EarthquakeProvider.LATITUDE_COLUMN) * 1E6;
				Double lngE6 = quakeCursor
						.getFloat(EarthquakeProvider.LONGITUDE_COLUMN) * 1E6;
				float mag = quakeCursor
						.getFloat(EarthquakeProvider.MAGNITUDE_COLUMN);

				long timeMillis = quakeCursor
						.getLong(EarthquakeProvider.DATE_COLUMN);

				GeoPoint g = new GeoPoint(latE6.intValue(), lngE6.intValue());

				// create an OverlayItem and add it to our list
				QuakeOverlayItem quakeOverlay = new QuakeOverlayItem(g,
						"title", "snippet", mag, timeMillis);

				myOverlays.add(quakeOverlay);

			} while (quakeCursor.moveToNext());
		}

		setLastFocusedIndex(-1); 

		populate();
	}

	// Handle tap events on overlay icons
	@Override
	protected boolean onTap(int i) {
		QuakeOverlayItem q = myOverlays.get(i);
		DecimalFormat decimalFormat = new DecimalFormat("##.000");

		DateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy hh:mm:ss");

		String toast = "M" + Float.toString(q.getMagnitude()) + "\n" + "("
				+ decimalFormat.format(q.getPoint().getLatitudeE6() / 1E6)
				+ " , "
				+ decimalFormat.format(q.getPoint().getLongitudeE6() / 1E6)
				+ ")" + "\n" + dateFormat.format(new Date(q.getTimeMillis()));
		Toast.makeText(context, toast, Toast.LENGTH_LONG).show();
		return (true);
	}

	/**
	 * Extend OverlayItem to add quake-specific fields TODO: scale the displayed
	 * icon to reflect quake magnitude, or choose a different icon (e.g. color)
	 * based on magnitude
	 * 
	 * @author mfaulk
	 * 
	 */
	private class QuakeOverlayItem extends OverlayItem {
		private final float magnitude;
		private final long timeMillis;

		/**
		 * 
		 * @param point
		 * @param title
		 * @param snippet
		 * @param magnitude
		 * @param latitude
		 * @param longitude
		 */
		public QuakeOverlayItem(GeoPoint point, String title, String snippet,
				float magnitude, long timeMillis) {
			super(point, title, snippet);
			this.magnitude = magnitude;
			this.timeMillis = timeMillis;
		}

		public float getMagnitude() {
			return magnitude;
		}

		public long getTimeMillis() {
			return timeMillis;
		}

	}

}
